{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Digits手写数字数据集\n",
    "\n",
    "- 导入Digits数据集\n",
    "- 可视化一些样本数据\n",
    "- 探索数据的分布规律\n",
    "- T-SNE非线性降维\n",
    "- PCA主成分分析降维"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "#导入工具包\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "#忽略系统的警告提示\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "#正常显示中文标签\n",
    "plt.rcParams['font.sans-serif']=['SimHei']\n",
    "#用来正常显示负号\n",
    "plt.rcParams['axes.unicode_minus']=False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.导入digits数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import datasets\n",
    "\n",
    "digits = datasets.load_digits()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'data': array([[ 0.,  0.,  5., ...,  0.,  0.,  0.],\n",
       "        [ 0.,  0.,  0., ..., 10.,  0.,  0.],\n",
       "        [ 0.,  0.,  0., ..., 16.,  9.,  0.],\n",
       "        ...,\n",
       "        [ 0.,  0.,  1., ...,  6.,  0.,  0.],\n",
       "        [ 0.,  0.,  2., ..., 12.,  0.,  0.],\n",
       "        [ 0.,  0., 10., ..., 12.,  1.,  0.]]),\n",
       " 'target': array([0, 1, 2, ..., 8, 9, 8]),\n",
       " 'target_names': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),\n",
       " 'images': array([[[ 0.,  0.,  5., ...,  1.,  0.,  0.],\n",
       "         [ 0.,  0., 13., ..., 15.,  5.,  0.],\n",
       "         [ 0.,  3., 15., ..., 11.,  8.,  0.],\n",
       "         ...,\n",
       "         [ 0.,  4., 11., ..., 12.,  7.,  0.],\n",
       "         [ 0.,  2., 14., ..., 12.,  0.,  0.],\n",
       "         [ 0.,  0.,  6., ...,  0.,  0.,  0.]],\n",
       " \n",
       "        [[ 0.,  0.,  0., ...,  5.,  0.,  0.],\n",
       "         [ 0.,  0.,  0., ...,  9.,  0.,  0.],\n",
       "         [ 0.,  0.,  3., ...,  6.,  0.,  0.],\n",
       "         ...,\n",
       "         [ 0.,  0.,  1., ...,  6.,  0.,  0.],\n",
       "         [ 0.,  0.,  1., ...,  6.,  0.,  0.],\n",
       "         [ 0.,  0.,  0., ..., 10.,  0.,  0.]],\n",
       " \n",
       "        [[ 0.,  0.,  0., ..., 12.,  0.,  0.],\n",
       "         [ 0.,  0.,  3., ..., 14.,  0.,  0.],\n",
       "         [ 0.,  0.,  8., ..., 16.,  0.,  0.],\n",
       "         ...,\n",
       "         [ 0.,  9., 16., ...,  0.,  0.,  0.],\n",
       "         [ 0.,  3., 13., ..., 11.,  5.,  0.],\n",
       "         [ 0.,  0.,  0., ..., 16.,  9.,  0.]],\n",
       " \n",
       "        ...,\n",
       " \n",
       "        [[ 0.,  0.,  1., ...,  1.,  0.,  0.],\n",
       "         [ 0.,  0., 13., ...,  2.,  1.,  0.],\n",
       "         [ 0.,  0., 16., ..., 16.,  5.,  0.],\n",
       "         ...,\n",
       "         [ 0.,  0., 16., ..., 15.,  0.,  0.],\n",
       "         [ 0.,  0., 15., ..., 16.,  0.,  0.],\n",
       "         [ 0.,  0.,  2., ...,  6.,  0.,  0.]],\n",
       " \n",
       "        [[ 0.,  0.,  2., ...,  0.,  0.,  0.],\n",
       "         [ 0.,  0., 14., ..., 15.,  1.,  0.],\n",
       "         [ 0.,  4., 16., ..., 16.,  7.,  0.],\n",
       "         ...,\n",
       "         [ 0.,  0.,  0., ..., 16.,  2.,  0.],\n",
       "         [ 0.,  0.,  4., ..., 16.,  2.,  0.],\n",
       "         [ 0.,  0.,  5., ..., 12.,  0.,  0.]],\n",
       " \n",
       "        [[ 0.,  0., 10., ...,  1.,  0.,  0.],\n",
       "         [ 0.,  2., 16., ...,  1.,  0.,  0.],\n",
       "         [ 0.,  0., 15., ..., 15.,  0.,  0.],\n",
       "         ...,\n",
       "         [ 0.,  4., 16., ..., 16.,  6.,  0.],\n",
       "         [ 0.,  8., 16., ..., 16.,  8.,  0.],\n",
       "         [ 0.,  1.,  8., ..., 12.,  1.,  0.]]]),\n",
       " 'DESCR': \".. _digits_dataset:\\n\\nOptical recognition of handwritten digits dataset\\n--------------------------------------------------\\n\\n**Data Set Characteristics:**\\n\\n    :Number of Instances: 5620\\n    :Number of Attributes: 64\\n    :Attribute Information: 8x8 image of integer pixels in the range 0..16.\\n    :Missing Attribute Values: None\\n    :Creator: E. Alpaydin (alpaydin '@' boun.edu.tr)\\n    :Date: July; 1998\\n\\nThis is a copy of the test set of the UCI ML hand-written digits datasets\\nhttp://archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits\\n\\nThe data set contains images of hand-written digits: 10 classes where\\neach class refers to a digit.\\n\\nPreprocessing programs made available by NIST were used to extract\\nnormalized bitmaps of handwritten digits from a preprinted form. From a\\ntotal of 43 people, 30 contributed to the training set and different 13\\nto the test set. 32x32 bitmaps are divided into nonoverlapping blocks of\\n4x4 and the number of on pixels are counted in each block. This generates\\nan input matrix of 8x8 where each element is an integer in the range\\n0..16. This reduces dimensionality and gives invariance to small\\ndistortions.\\n\\nFor info on NIST preprocessing routines, see M. D. Garris, J. L. Blue, G.\\nT. Candela, D. L. Dimmick, J. Geist, P. J. Grother, S. A. Janet, and C.\\nL. Wilson, NIST Form-Based Handprint Recognition System, NISTIR 5469,\\n1994.\\n\\n.. topic:: References\\n\\n  - C. Kaynak (1995) Methods of Combining Multiple Classifiers and Their\\n    Applications to Handwritten Digit Recognition, MSc Thesis, Institute of\\n    Graduate Studies in Science and Engineering, Bogazici University.\\n  - E. Alpaydin, C. Kaynak (1998) Cascading Classifiers, Kybernetika.\\n  - Ken Tang and Ponnuthurai N. Suganthan and Xi Yao and A. Kai Qin.\\n    Linear dimensionalityreduction using relevance weighted LDA. School of\\n    Electrical and Electronic Engineering Nanyang Technological University.\\n    2005.\\n  - Claudio Gentile. A New Approximate Maximal Margin Classification\\n    Algorithm. NIPS. 2000.\"}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "digits"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['data', 'target', 'target_names', 'images', 'DESCR'])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#打印digits数据集中包含的主要内容\n",
    "digits.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".. _digits_dataset:\n",
      "\n",
      "Optical recognition of handwritten digits dataset\n",
      "--------------------------------------------------\n",
      "\n",
      "**Data Set Characteristics:**\n",
      "\n",
      "    :Number of Instances: 5620\n",
      "    :Number of Attributes: 64\n",
      "    :Attribute Information: 8x8 image of integer pixels in the range 0..16.\n",
      "    :Missing Attribute Values: None\n",
      "    :Creator: E. Alpaydin (alpaydin '@' boun.edu.tr)\n",
      "    :Date: July; 1998\n",
      "\n",
      "This is a copy of the test set of the UCI ML hand-written digits datasets\n",
      "http://archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits\n",
      "\n",
      "The data set contains images of hand-written digits: 10 classes where\n",
      "each class refers to a digit.\n",
      "\n",
      "Preprocessing programs made available by NIST were used to extract\n",
      "normalized bitmaps of handwritten digits from a preprinted form. From a\n",
      "total of 43 people, 30 contributed to the training set and different 13\n",
      "to the test set. 32x32 bitmaps are divided into nonoverlapping blocks of\n",
      "4x4 and the number of on pixels are counted in each block. This generates\n",
      "an input matrix of 8x8 where each element is an integer in the range\n",
      "0..16. This reduces dimensionality and gives invariance to small\n",
      "distortions.\n",
      "\n",
      "For info on NIST preprocessing routines, see M. D. Garris, J. L. Blue, G.\n",
      "T. Candela, D. L. Dimmick, J. Geist, P. J. Grother, S. A. Janet, and C.\n",
      "L. Wilson, NIST Form-Based Handprint Recognition System, NISTIR 5469,\n",
      "1994.\n",
      "\n",
      ".. topic:: References\n",
      "\n",
      "  - C. Kaynak (1995) Methods of Combining Multiple Classifiers and Their\n",
      "    Applications to Handwritten Digit Recognition, MSc Thesis, Institute of\n",
      "    Graduate Studies in Science and Engineering, Bogazici University.\n",
      "  - E. Alpaydin, C. Kaynak (1998) Cascading Classifiers, Kybernetika.\n",
      "  - Ken Tang and Ponnuthurai N. Suganthan and Xi Yao and A. Kai Qin.\n",
      "    Linear dimensionalityreduction using relevance weighted LDA. School of\n",
      "    Electrical and Electronic Engineering Nanyang Technological University.\n",
      "    2005.\n",
      "  - Claudio Gentile. A New Approximate Maximal Margin Classification\n",
      "    Algorithm. NIPS. 2000.\n"
     ]
    }
   ],
   "source": [
    "#打印digits数据集说明\n",
    "print(digits.DESCR)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "#获取digits数据集的样本和特征\n",
    "samples = digits.data\n",
    "label = digits.target"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.可视化其中一些样本"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'True label:1')"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#可视化其中一个样本\n",
    "\n",
    "plt.imshow(samples[1].reshape(8,8))\n",
    "plt.title('True label:{}'.format(label[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAAKPCAYAAABgurA7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nO3de7huZV0v/O9PWJwVURS2EioiGGwldIXiK7o8UGLtRM2tZbuNwUtpdVXWvjxkW3e7qNdKbbuDojTLDA+9Lx52HjNhU6KIUZqK5BE3CogiIsb5fv+YE1kYsMaYaz5zzvten891reuaa87fHOMe67vmnN85nucZo1prAQAYyV3WewEAAKtNwQEAhqPgAADDUXAAgOEoOADAcBQcAGA4a15wqupXqurSqvrXqrpq+e3HreH+T6iq102Y21JVZ61g+5M/r6oeXFUXVNUlVXXC3H2tFxn+m/l7V9X/mbuf9STD28w+vKo+VVU3VNW7q2rvuftbDzK8zeyeVfX7VXVOVf33qtp57v7Wgwxv93P2raor5u7r9qx5wWmt/W5rbf8kb0rygtba/q21D6z1OjaI1yf5H0kemOS5VfU967yeSWR4q6q6d5K3Jrnveq9lDhkuqapK8rokL02yT5Kbkvzceq5pKhnexquSfDPJTyV5RJIT13c508jwdr0iyT1XY0Meolony2Xmvkle11q7Nskbkhy3vqtiBU5M8uvrvQhWbPckL2mtvbm19q0k709ywDqvifk+n+RlrbV/SfKOJIes83pYgap6YpZ+4f/SamxvQxWcqjqrqn60qt5aVX+7/L7bnOKqqtfd8nBOVT25qi6sqsuq6mXbsd/jq+ozVfXlqnr1Vh+6W1W9p6q+UlUv2Wr+qOWHli6vqtOXfwvc1j4eVVV/vdW7Dkjy8XbrpaS/mOTglR7DRrGDZZgkv91ae/dK170R7UgZtta+3Vp721YjT0zyoZUew0axI2WYJK21U1prN1XVQUlOSHLmSo9ho9jRMqyq3ZL8fpKTkty80vVvbUMVnGWnJHltkqfe2VBV3SvJq5P8QJaKwTOq6sgV7vOnkzwjyYFJtlTVYcvvPyLJryU5LMlJVbW5qnbJ0tmWE5bnH5Dk+G3toLX2wdbaD231rp2ydEr1FtckufsK17/R7CgZZquCOpodJsOtjmXL8j7euML1bzQ7VIZVdXCSc5J8O8lHVrj+jWZHyvClSc5orX1qhev+NzZiwXlta+3trbWr7uDjt7TDR2bpIZ7zkvxLkvskOXyF+/ypJMckOSPJg5Lce/n9H2utnddauzLJO5M8KsmhSe6f5D1JvpDk4VkKfK4rc9tCs3tWqbVuADtKhiPboTKsqr2S/HGSn2mtXbfS7WwwO1SGrbXPZOmH7OeSvGil29lgdogMq+ohSY5N8v+scM23ayM+03xbp4dveTJnJflAa+24ZOlZ9FlBQaiquyc5P8nvJPnNJPfa6sNb/3Z+c5YKYSX5TGvte5c/f7csnY2Z66IkD6qqTa21G5JsTtLVK3HuxI6S4ch2tAxPT/LOwR5u3CEyXD6L8IOttXcsP0x1ZpJnz93OBrVDZJjkh7N09udLy49w3auqLk3y/a21FT8fZyOewflu30xyQC15SJLHLr//Q0mOrKpDl/+Dvy9Lp+fmOjjJjUlOzdJZlIdv9bGHVtXDaullo8cl+XCSC5PsUVXHVNVdsvRKqJPm7nS51Lw/ye9X1Q9k6bTg21ew/h4MmeEOZtgMq+oFy/v/Lyv5/I4MmWFr7fokr6yqJy0//+PpWTqTMaJRM/yt1to9l19Ftn+SLy2/vV1PNu6h4FyQ5ONJ/j7JC7L0kty01i7P0j/k27N0auzc73qy4FT/tPznK0n+6/K+bnkG/qeyFPSnk/xla+3c5S+mZ2bp8c5Lklyb5LRt7eT2nlSV5JeS7Jbk97L0So6PrWD9PRg5wx3FyBm+MEun2i+upeuQvHkF6+/ByBn+WJbOOnw5yXVZetn4iEbOcNXVuM+RBAB2VD2cwQEAmEXBAQCGo+AAAMNRcACA4Sg4AMBwVvVCf7vUrm237Lmam/yOG/edvt399//65NlLrpl3d4Td/s8Nk2fbDTfO2vZU1+aaXN+u2+b9PlZikRnOWseDp3fvXe8y79/5G5fddfLsTl+7Zta2p9oRMrz57tPXcP/vuWzWti+94W6TZ6+/cHEXCL86V17RWrvXtifnWWSG1993+nb//T2/Onn26zfPu77b1z49fR2L+l6a9JnhHLXz9B/zNx8075xHXXT93OUsxB1luKoFZ7fsmUfUE1Zzk99xxdOPnjz7X355+q1kfu2jT5m1jkOe/5XJszdeOu+b9lQfbu9fyHaTxWY4x33+bHoJedAel8/a9ltf8fjJs/u87txZ255qR8jw249/xOTZ17zqFbO2/VtfedLk2S8/8upZ257jb9pffXER211khp//+enfS8/7z9u8pMl3vPHqfWat4/WPPWry7KK+lyZ9ZjjHTvvee9tDy/711N1nbXuXYxfyTzfbHWXoISoAYDiTCk5Vvaaqzq2tbpFOX2TYPxn2T4b9k2E/tllwquppSXZqrR2d5KCqetDil8VqkmH/ZNg/GfZPhn2ZcgZnS5Jb7s3y3iSP3vqDVXVyVZ1fVeffkOtWeXmski2RYe+2RIa92xIZ9m5LZNiNKQVnzyzdRCtJvp5kv60/2Fo7vbW2ubW2eVN2Xe31sTpk2D8Z9k+G/ZNhR6YUnG9l6bbpSbLXxM9hY5Fh/2TYPxn2T4YdmRLOR3PrabgjsnQrdvoiw/7JsH8y7J8MOzLlOjhvTXJOVd0nyXFJHrnYJbEAMuyfDPsnw/7JsCPbLDittW9W1ZYkxyZ5eWvtqoWv6nbMuXjfs+565eTZV939W7PW8df/8J7Jsw9/2XNnbXvf0xdzUbmNkuEcX7j6HpNn//TAc2Zt+48fc8zk2X1eN2vTC7NRMrz5sUdOnj3nD/5o8uxF0y8QniR5yj0vmDx7Wg6et/EFWVSGF502/YJ5SfJbj5/+vfTf//7zJs/+8y+cOmsdrz7m/pNn93rL4i70N8dG+Tqc4/PPnf7///p/nnfV74OzMS70d0cmXcm4tXZlbn3mOB2SYf9k2D8Z9k+G/fAEKQBgOAoOADAcBQcAGI6CAwAMR8EBAIaj4AAAw1FwAIDhKDgAwHAUHABgOAoOADCcSbdqWIQbH//wWfPPuus/Tp497knPmjy798cunLWO//h3T5g8+/Ujb5q17X1nTfdnzn2M/uiQ/zljy3vOWsfdPr7LrHlu9bnjd508e8oVh06efc37HzdrHZ995h9Onj1t1pb78+DTvjlr/vX/bfq9q15y9hmTZ9949T6z1rHXWz48a55b7bTfvSfP/qenvX/y7Jv+dPrPtyTZ6fDpX+Nz3fSJT2/3NpzBAQCGo+AAAMPZ5kNUVbV3kjcm2SnJNUme2Vq7ftELY/XIsH8y7J8M+yfDvkw5g/PsJK9orf1AkkuTPGmxS2IBZNg/GfZPhv2TYUe2eQantXbqVn+9V5LLF7ccFkGG/ZNh/2TYPxn2ZfKrqKrq6CT7tNY+9F3vPznJyUmyW/ZY3dWxqmTYPxn2T4b9k2EfJhWcqrpHklcnefp3f6y1dnqS05PkbnWPtqqrY9XIsH8y7J8M+yfDfmzzOThVtUuStyR5UWvti4tfEqtNhv2TYf9k2D8Z9mXKk4xPTPKwJL9aVWdV1TMXvCZWnwz7J8P+ybB/MuzIlCcZn5bxLwY6NBn2T4b9k2H/ZNiXdbtVw7X3nLfrl1z+kMmzN8+8/cIcH/n4Axe27d5c/LJHzZp/23N+Z/LsIZvm3X5hjvu+92uTZ+fdbGN8h/725ybPvuni6Zd9f9cvTv+/kSSP+8SPT57dJWM/kjD7+91DHzx59Fl3vXLy7H/83LzL/O+8//SfATdeetmsbY/u8889ePLsq/Y+c/Ls2a/cfdY6PvXazZNn73LVvJ/5B//SrPHb3+f2bwIAYGNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4azfrRr2mdet3nDu0ZNnD8l5c5cz2c57Xz959sardlnYOjaCA1/2wVnzv3jaUyfPvvOC985dzmQ37LvH5NnRfwPYab97z5r/9AsPmjx74hPeP3c5k+3+E/86edbtNm5rzq0dfuhhPzh59sh3f3neQt49ffSCJ91n1qZ7u7XDlSdM//mWJJ86+dTJs4efe/Lk2QPyiVnr+PyT/mTy7BG/87xZ214No3//BgB2QAoOADCcSQWnqvarqgsWvRgWR4b9k2H/ZNg/GfZj6hmc300y7z7qbDQy7J8M+yfD/smwE9ssOFX1+CTXJLl08cthEWTYPxn2T4b9k2Ff7rTgVNUuSX4tyQvvZObkqjq/qs6/Idet9vrYTjLsnwz7J8P+ybA/2zqD88Ikp7bWvnFHA62101trm1trmzdl19VdHatBhv2TYf9k2D8ZdmZbBeeJSX62qs5K8n1VNf1F72wUMuyfDPsnw/7JsDN3eqG/1tpjbnm7qs5qrZ20+CWxmmTYPxn2T4b9k2F/Jl8Hp7W2ZYHrYA3IsH8y7J8M+yfDPrjQHwAwnHW7F9VuV948a/77H/LZybNXzdjuzvvvN2sdzzzso5Nn3/yuR8/aNmvj8odNv4TF/mcvcCEbwKd+68BZ859/0h8uZB1HvfhXZs3vc9m5C1kHtzXnnk5z7xf1tdfedfLsZS+9x6xtH/Lcvu5FtetV834eXnTDNZNnP3H0GybPnvKxQ2etY477/uVnZs2vxj3knMEBAIaj4AAAw1FwAIDhKDgAwHAUHABgOAoOADAcBQcAGI6CAwAMR8EBAIaj4AAAw1m3WzXc7dNzbqiQvPSA/zV59idPfv7k2U3Hf3XWOuZ4wItcTp6N7eA/m3dB9FM2T7+U+4v3/fTk2fNOOW3WOh737KdMnr3mDfNuIbDP68b+ur3otKMmz97nb2vy7LX7zPt9+c8Pe8Xk2eO/8dxZ2+7NHmd+eNb8z5/5f02evfmxR06e/YM//5+z1nH4uSdPnj3gsk/M2vZqcAYHABiOggMADGdywamqU6vqPyxyMSyWDPsnw/7JsH8y7MOkglNVxyTZv7X2jgWvhwWRYf9k2D8Z9k+G/dhmwamqTUn+OMkXqmr6M/vYMGTYPxn2T4b9k2FfppzB+ckkn0zy8iRHVdXPb/3Bqjq5qs6vqvNvyHWLWCPbT4b9k2H/ZNg/GXZkSsE5MsnprbVLk/xFksdt/cHW2umttc2ttc2bsusi1sj2k2H/ZNg/GfZPhh2ZUnA+k+Sg5bc3J/ni4pbDgsiwfzLsnwz7J8OOTLnQ32uSvLaqnpVkU5IfXeySWAAZ9k+G/ZNh/2TYkW0WnNba1UmesQZrYUFk2D8Z9k+G/ZNhX1zoDwAYzrrdi+rmj104a/6Zp/3y5NmX/PIZk2df9dknzFrHR75vp1nz3Oqmyy6fPPu4T0x/BeYHDn/brHXc+OgZ90F75axNd+cuZ18wa/7sh+4+efYDj33O5NkbX/L1WeuYk/kDHnPSrG3v87pZ493Z9I3p38N+/jfeuLB1HP/B6feXOujH/3Fh6xjdpiu+PXn2kE17ztr2Pf5ir7nLWVPO4AAAw1FwAIDhKDgAwHAUHABgOAoOADAcBQcAGI6CAwAMR8EBAIaj4AAAw1FwAIDhVGtt9TZW9dXc/u3j901yxartaONZ6+O7X2vtXovYsAzXjAxX33oc30JylOGakuHq2jAZrmrBuSNVdX5rbfPCd7RORj++ZPxjHP34kvGPcfTjS8Y/xtGPLxn/GDfS8XmICgAYjoIDAAxnrQrO6Wu0n/Uy+vEl4x/j6MeXjH+Mox9fMv4xjn58yfjHuGGOb02egwMAsJY8RAUADEfB2Q5VtXNVXVxVZy3/ech6r4l5ZNg/GfZPhv3biBnuvOgdVNVrkhyW5K9ba7+x6P2tsYcmOaO19oL1XsgiybB/MuyfDPsnw7W10DM4VfW0JDu11o5OclBVPWiR+1sHj0zyw1V1XlW9pqoWXhjXmgz7J8P+ybB/Mlx7i36IakuSNy+//d4kj17w/tbaR5I8sbV2VJJNSZ68zutZhC2RYe+2RIa92xIZ9m5LZLimFl1w9kxyyfLbX0+y34L3t9Y+1lr7yvLb5ycZrZEnMhyBDPsnw/7JcI0tuuB8K8nuy2/vtQb7W2uvr6ojqmqnJMcn+af1XtACyLB/MuyfDPsnwzW26H/gj+bW03BHJPnCgve31n49yeuT/GOSc1trf7PO61kEGfZPhv2TYf9kuMYWeqG/qrpbknOSvD/JcUke2Vq7amE7ZNXJsH8y7J8M+yfDtbfwKxlX1T5Jjk3yv1trly50ZyyEDPsnw/7JsH8yXFtu1QAADGe0JzkBACg4AMB4FBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA4Sg4AMBwFBwAYDgKDgAwHAUHABiOggMADEfBAQCGo+AAAMNRcACA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\n",
      "text/plain": [
       "<Figure size 576x1440 with 10 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#可视化前10个样本\n",
    "\n",
    "plt.figure(figsize = (8,20))\n",
    "\n",
    "for i in range(10):\n",
    "    plt.subplot(2,5,i+1)\n",
    "    plt.imshow(samples[i].reshape(8,8))\n",
    "    plt.title('True label:{}'.format(label[i]))\n",
    "plt.tight_layout()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3.T-SNE数据降维"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.manifold import TSNE\n",
    "\n",
    "tsne = TSNE(n_components = 2,init = 'pca',random_state = 0)\n",
    "X_tsne = tsne.fit_transform(samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_tsne.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_tsne[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#对降维后的数据进行归一化处理\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "X_tsne = MinMaxScaler().fit_transform(X_tsne)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_tsne[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#可视化降维后的结果\n",
    "\n",
    "plt.figure(figsize = (10,8))\n",
    "colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'purple', 'coral', 'lime']\n",
    "for i in range(samples.shape[0]):\n",
    "    plt.text(X_tsne[i,0],X_tsne[i,1],str(label[i]),color=colors[label[i]],fontdict = {'weight':'bold','size':15})\n",
    "plt.xticks([])\n",
    "plt.yticks([])\n",
    "plt.title('TSNE降维 - 手写数字识别数据集展示')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#将digits数据集降到3维\n",
    "\n",
    "from sklearn.manifold import TSNE\n",
    "\n",
    "tsne = TSNE(n_components = 3,init = 'pca',random_state = 0)\n",
    "X_tsnes = tsne.fit_transform(samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_tsnes.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_tsnes[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list(range(10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mpl_toolkits.mplot3d import Axes3D\n",
    "fig = plt.figure(figsize = (8,8))\n",
    "ax1 = Axes3D(fig)\n",
    "\n",
    "for lab,color,category in zip(label,colors,list(range(10))):\n",
    "    ax1.scatter3D(X_tsnes[label == lab,0],\n",
    "               X_tsnes[label == lab,1],\n",
    "               X_tsnes[label == lab,2],\n",
    "               label = category,\n",
    "               c = color)\n",
    "ax1.set_xlabel('X',fontdict = {'size':15,'color':'red'})\n",
    "ax1.set_ylabel('Y',fontdict = {'size':15,'color':'red'})\n",
    "ax1.set_zlabel('Z',fontdict = {'size':15,'color':'red'})\n",
    "ax1.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 4.PCA降维"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.decomposition import PCA\n",
    "\n",
    "pca = PCA(n_components = 2)\n",
    "X_pca = pca.fit_transform(samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_pca.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#可视化降维后的结果\n",
    "\n",
    "plt.figure(figsize = (10,8))\n",
    "colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'purple', 'coral', 'lime']\n",
    "for i in range(samples.shape[0]):\n",
    "    plt.text(X_pca[i,0],X_pca[i,1],str(label[i]),color=colors[label[i]],fontdict = {'weight':'bold','size':15})\n",
    "plt.xticks([])\n",
    "plt.yticks([])\n",
    "plt.title('PCA降维 - 手写数字识别数据集展示')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#将原始数据降至3维\n",
    "pca = PCA(n_components = 3,random_state = 0)\n",
    "X_pca3 = pca.fit_transform(samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_pca3.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#可视化降维后的结果\n",
    "fig = plt.figure(figsize = (8,8))\n",
    "ax1 = Axes3D(fig)\n",
    "\n",
    "for lab,color,category in zip(label,colors,list(range(10))):\n",
    "    ax1.scatter3D(X_pca3[label == lab,0],\n",
    "               X_pca3[label == lab,1],\n",
    "               X_pca3[label == lab,2],\n",
    "               label = category,\n",
    "               c = color)\n",
    "ax1.set_xlabel('X',fontdict = {'size':15,'color':'red'})\n",
    "ax1.set_ylabel('Y',fontdict = {'size':15,'color':'red'})\n",
    "ax1.set_zlabel('Z',fontdict = {'size':15,'color':'red'})\n",
    "ax1.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
